package com.thz.system.service.matting.impl;

import com.thz.common.dto.matting.ConversionImageMattingRequestDTO;
import com.thz.common.entity.ConversionRecord;
import com.thz.common.entity.ConversionRecordImageMatting;
import com.thz.common.enums.ConversionStatus;
import com.thz.common.enums.ConversionType;
import com.thz.common.utils.FileUtils;
import com.thz.system.config.CosConfig;
import com.thz.system.config.MattingProperties;
import com.thz.system.mapper.matting.ConversionImageMattingMapper;
import com.thz.system.service.matting.IAsyncConversionImageMattingService;
import com.thz.system.service.record.IConversionRecordService;
import com.thz.system.utils.ImageMattingUtils;
import com.thz.system.utils.cos.CosFileUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;

import java.awt.*;
import java.io.File;
import java.time.LocalDateTime;

/**
 * 异步图片抠图服务实现类
 * 使用专用线程池处理抠图任务，避免阻塞主线程
 * 
 * @author THZ
 * @date 2025
 */
@Slf4j
@Service
public class AsyncConversionImageMattingServiceImpl implements IAsyncConversionImageMattingService {
    
    @Autowired
    private ImageMattingUtils imageMattingUtils;
    
    @Autowired
    private ConversionImageMattingMapper conversionImageMattingMapper;
    
    @Autowired
    private IConversionRecordService conversionRecordService;
    
    @Autowired
    private CosFileUtils cosFileUtils;
    
    @Autowired
    private CosConfig cosConfig;
    
    @Autowired
    private MattingProperties mattingProperties;
    
    @Override
    @Async("imageMattingExecutor")
    public void executeImageMattingAsync(
            Long recordId,
            String imageFilePath,
            ConversionImageMattingRequestDTO requestDTO,
            String ipAddress,
            Long userId) {
        
        log.info("[异步抠图] 开始处理任务，recordId={}, 线程={}", recordId, Thread.currentThread().getName());
        
        File imageFile = null;
        File outputFile = null;
        
        try {
            // 1. 获取抠图记录
            ConversionRecordImageMatting record = conversionImageMattingMapper.selectById(recordId);
            if (record == null) {
                log.error("[异步抠图] 记录不存在，recordId={}", recordId);
                return;
            }
            
            // 2. 更新状态为转换中
            record.setConversionStatus(ConversionStatus.CONVERTING.getCode());
            record.setUpdateTime(LocalDateTime.now());
            conversionImageMattingMapper.updateById(record);
            
            // 3. 下载图片到本地临时目录
            String tempPath = System.getProperty("java.io.tmpdir") + "/image_" + System.currentTimeMillis() + "." + 
                    FileUtils.getFileExtension(record.getOriginalFilename());
            cosFileUtils.downloadToLocal(imageFilePath, tempPath);
            imageFile = new File(tempPath);
            log.info("[异步抠图] 图片已下载到临时目录: {}", tempPath);
            
            // 4. 准备输出文件（使用系统临时目录）
            String outputFilename = FileUtils.generateUniqueFilename(record.getOriginalFilename())
                    .replaceFirst("\\.[^.]+$", ".png");
            // 使用系统临时目录，无需配置
            String tempDir = System.getProperty("java.io.tmpdir");
            outputFile = new File(tempDir, outputFilename);
            
            // 5. 执行抠图
            Color bgColor = imageMattingUtils.parseColor(requestDTO.getBackgroundColor());
            String algorithm = requestDTO.getAlgorithm() != null ? requestDTO.getAlgorithm().toLowerCase() : "isnet-general-use";
            int quality = requestDTO.getQuality() != null ? requestDTO.getQuality() : 95;
            String processingMode = requestDTO.getProcessingMode() != null ? requestDTO.getProcessingMode() : "balanced";
            
            if (processingMode != null && processingMode.equals("quality")) {
                processingMode = "balanced"; // 屏蔽高质量模式
            }
            // 大图自动切换到快速模式（阈值可配置）
            try {
                Dimension dims = imageMattingUtils.getImageDimensions(imageFile.getAbsolutePath());
                int maxDim = Math.max(dims.width, dims.height);
                int threshold = mattingProperties != null ? Math.max(800, mattingProperties.getAutoFastThreshold()) : 1800;
                if (maxDim >= threshold && "balanced".equalsIgnoreCase(processingMode)) {
                    processingMode = "fast";
                }
            } catch (Exception ignore) {}
            
            log.info("[异步抠图] 开始执行抠图，algorithm={}, quality={}, processingMode={}", algorithm, quality, processingMode);
            long startTime = System.currentTimeMillis();
            
            boolean success = imageMattingUtils.removeBackground(
                    imageFile.getAbsolutePath(),
                    outputFile.getAbsolutePath(),
                    algorithm,
                    bgColor,
                    quality,
                    processingMode
            );
            
            long elapsed = System.currentTimeMillis() - startTime;
            log.info("[异步抠图] 抠图完成，耗时={}ms", elapsed);
            
            if (!success) {
                throw new RuntimeException("抠图处理失败");
            }
            
            // 6. 调整尺寸（如果需要）
            if (requestDTO.getWidth() != null || requestDTO.getHeight() != null) {
                int targetWidth = requestDTO.getWidth() != null ? requestDTO.getWidth() : 0;
                int targetHeight = requestDTO.getHeight() != null ? requestDTO.getHeight() : 0;
                
                String tempFilename = "temp_" + outputFilename;
                File tempFile = new File(tempDir, tempFilename);
                
                imageMattingUtils.resizeImage(
                        outputFile.getAbsolutePath(),
                        tempFile.getAbsolutePath(),
                        targetWidth,
                        targetHeight,
                        requestDTO.getKeepAspectRatio(),
                        quality
                );
                
                outputFile.delete();
                tempFile.renameTo(outputFile);
                
                // 🔑 调整尺寸后再次压缩优化
                long sizeBeforeCompress = outputFile.length();
                log.info("[异步抠图] 调整尺寸后压缩优化，文件={}, 大小={}字节", outputFile.getAbsolutePath(), sizeBeforeCompress);
                imageMattingUtils.compressPngFile(outputFile.getAbsolutePath(), quality);
                long sizeAfterCompress = outputFile.length();
                log.info("[异步抠图] 压缩优化完成，文件={}, 大小={}字节 (减少{}%)", 
                        outputFile.getAbsolutePath(), sizeAfterCompress,
                        sizeBeforeCompress > 0 ? String.format("%.1f", (1.0 - (double) sizeAfterCompress / sizeBeforeCompress) * 100) : "0");
            }
            
            // 7. 获取输出文件信息（压缩后的大小）
            long outputSize = outputFile.length();
            Dimension outputDimensions = imageMattingUtils.getImageDimensions(outputFile.getAbsolutePath());
            
            // 8. 上传输出文件到COS
            String outputCosPath = cosFileUtils.uploadLocalFile(outputFile, cosConfig.getOutputPrefix());
            log.info("[异步抠图] 输出文件已上传到COS: {}", outputCosPath);
            
            // 9. 更新转换记录
            record.setOutputFilename(outputFilename);
            record.setOutputFilePath(outputCosPath);
            record.setOutputFileSize(outputSize);
            record.setOutputWidth(outputDimensions.width);
            record.setOutputHeight(outputDimensions.height);
            record.setConversionStatus(ConversionStatus.SUCCESS.getCode());
            record.setUpdateTime(LocalDateTime.now());
            conversionImageMattingMapper.updateById(record);
            
            // 10. 更新统一转换记录表（使用原图作为缩略图）
            ConversionRecord unifiedRecord = new ConversionRecord();
            unifiedRecord.setUserId(record.getUserId());
            unifiedRecord.setIpAddress(ipAddress);
            unifiedRecord.setConversionType(ConversionType.IMAGE_MATTING.getCode());
            unifiedRecord.setReferenceId(record.getId());
            unifiedRecord.setOriginalFilename(record.getOriginalFilename());
            unifiedRecord.setOutputFilename(outputCosPath);
            unifiedRecord.setThumbnailFilename(record.getOriginalFilePath()); // 🔑 使用抠图后的结果作为缩略图
            unifiedRecord.setOriginalFileSize(record.getOriginalFileSize());
            unifiedRecord.setOutputFileSize(record.getOutputFileSize());
            unifiedRecord.setOutputWidth(record.getOutputWidth());
            unifiedRecord.setOutputHeight(record.getOutputHeight());
            unifiedRecord.setConversionStatus(record.getConversionStatus());
            unifiedRecord.setCreateTime(record.getCreateTime());
            unifiedRecord.setUpdateTime(record.getUpdateTime());
            conversionRecordService.createRecord(unifiedRecord);
            
            log.info("[异步抠图] 任务完成，recordId={}", recordId);
            
        } catch (Exception e) {
            log.error("[异步抠图] 任务失败，recordId=" + recordId, e);
            
            // 更新失败状态
            try {
                ConversionRecordImageMatting record = conversionImageMattingMapper.selectById(recordId);
                if (record != null) {
                    record.setConversionStatus(ConversionStatus.FAILED.getCode());
                    record.setErrorMessage(e.getMessage());
                    record.setUpdateTime(LocalDateTime.now());
                    conversionImageMattingMapper.updateById(record);
                }
            } catch (Exception ex) {
                log.error("[异步抠图] 更新失败状态异常", ex);
            }
            
        } finally {
            // 清理临时文件
            if (imageFile != null && imageFile.exists()) {
                imageFile.delete();
                log.info("[异步抠图] 临时图片文件已删除: {}", imageFile.getAbsolutePath());
            }
            if (outputFile != null && outputFile.exists()) {
                outputFile.delete();
                log.info("[异步抠图] 临时输出文件已删除: {}", outputFile.getAbsolutePath());
            }
        }
    }
}

